/*============================================================================
 * Copyright 2009 VMware Inc.
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
 * use this file except in compliance with the License. You may obtain a copy 
 * of the License at: http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
 * License for the specific language governing permissions and limitations 
 * under the License.
 ============================================================================*/

package com.vmware.vcloud;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;

import com.vmware.vcloud.data.VCloudConstants;
import com.vmware.vcloud.data.VirtualHardwareItem;
import com.vmware.vcloud.data.VirtualHardwareSection;
import com.vmware.vcloud.data.XmlBuilder;
import com.vmware.vcloud.data.XmlUtil;
import com.vmware.vcloud.rest.RestClient;
import com.vmware.vcloud.tmrk.InternetService;
import com.vmware.vcloud.tmrk.PublicIpAddress;

/**
 * @author Steve Jin (sjin@vmware.com)
 */

public class VDC extends VCloudObject
{
	private List<Network> networks = new ArrayList<Network>();
	private List<VApp> vapps =  new ArrayList<VApp>();
	private List<Catalog> catalogs = new ArrayList<Catalog>();
	
	public VDC(RestClient rc, String urlPath) throws MalformedURLException
	{
		super(rc, urlPath);
	}
	
	public VDC(RestClient rc, String urlPath, String name) throws MalformedURLException
	{
		super(rc, urlPath, name);
	}
	
	public void parse() throws MalformedURLException
	{
		List<?> vas = root.element("ResourceEntities").elements("ResourceEntity");
		for(Object o: vas)
		{
			Element elem = (Element) o;
			VApp va = new VApp(rc, elem.attributeValue("href"), elem.attributeValue("name"));
			vapps.add(va);
		}
		
		List<?> nets = root.element("AvailableNetworks").elements("Network");
		
		for(Object o: nets)
		{
			Element elem = (Element) o;
			Network net = new Network(rc, elem.attributeValue("href"), elem.attributeValue("name"));
			networks.add(net);
		}
	}
	
	public VApp deployVAppFromTemplate(String templateUrl, String vAppName, String networkUrl, int numOfCPU, int memInMB) throws IOException
	{
		Map<String, String> prodProps = new HashMap<String, String>();
		prodProps.put("password", "secretPassword");
//		prodProps.put("row", "SpringOne");
//		prodProps.put("group", "Demo");
		
		VirtualHardwareItem vCPU = new VirtualHardwareItem();
		vCPU.instanceID = "1";
		vCPU.resourceType = "3";
		vCPU.virtualQuantity = Integer.toString(numOfCPU);
		
		VirtualHardwareItem vMem = new VirtualHardwareItem();
		vMem.instanceID = "2";
		vMem.resourceType = "4";
		vMem.virtualQuantity = Integer.toString(memInMB);
		
		VirtualHardwareSection vhs = new VirtualHardwareSection();
		vhs.vCPU = vCPU;
		vhs.vMem = vMem;
		
	    String reqBody = XmlBuilder.buildVAppTempateParams(
	    	templateUrl, vAppName, prodProps,
	    	vhs, networkUrl );

	    String resBody = rc.post(
	    		getURL() + "/action/instantiatevAppTemplate",
	    		reqBody,
	    		VCloudConstants.CONTENT_TYPE_INST_VAPP);
	    System.out.println("reqBody:" + reqBody);
	    System.out.println("resBody:" + resBody);
	    Document doc = XmlUtil.getDocument(resBody);
	    String vAppStr = doc.getRootElement().attributeValue("href");
	    
		return new VApp(rc, vAppStr, vAppName);
	}
	
	public InternetService addInternetService(String name, String protocol, int port, String description) throws IOException
	{
		String reqBody = XmlBuilder.buildAddInternetServiceReq(name, protocol, port,
				description);
			
		String resBody = rc.post(this.getURL()+"/internetServices", reqBody, "application/xml");
		System.out.println("addInternetService reqBody:" + reqBody);
		System.out.println("addInternetService resBody:" + resBody);
		Document doc = XmlUtil.getDocument(resBody);
	    Element root = doc.getRootElement();
	    String id = root.elementText("Id");
	    String href = "https://services.vcloudexpress.terremark.com/api/v0.8/" + "internetServices/" + id;
		
		return new InternetService(rc, href);
	}

	public VApp[] getVApps() throws Exception
	{
		loadContentIfNotYet();
		VApp[] vas = new VApp[vapps.size()];
		vapps.toArray(vas);
		return vas;
	}
	
	public Network[] getNetworks() throws Exception
	{
		loadContentIfNotYet();
		Network[] nets = new Network[networks.size()];
		networks.toArray(nets);
		return nets;
	}
	
	public Catalog[] getCatalogs() throws Exception
	{
		loadContentIfNotYet();
		Catalog[] cats = new Catalog[catalogs.size()];
		catalogs.toArray(cats);
		return cats;
	}
	
	public InternetService[] getAllInternetServices() throws IOException
	{
		String resBody = rc.get(getURL()+"/internetServices");
		
		List<?> isList = XmlUtil.getRoot(resBody).elements();
		InternetService[] iss = new InternetService[isList.size()];
		
	    for(int i=0; i< isList.size(); i++)
	    {
	    	Element isElem = (Element) isList.get(i);
	    	iss[i] = XmlUtil.createInternetService(rc, isElem);
	    }
		
	    return iss;
	}
	
	public PublicIpAddress[] getAllPublicIpAddresses() throws IOException
	{
		String resBody = rc.get(getURL()+"/publicIps");
		
	    List<?> piaList = XmlUtil.getRoot(resBody).elements();
	    PublicIpAddress[] pias = new PublicIpAddress[piaList.size()];
	    
	    for(int i=0; i<piaList.size(); i++)
	    {
	    	Element piaElem = (Element) piaList.get(i);
	    	pias[i] = XmlUtil.createPublicIpAddress(rc, piaElem);
	    }

	    return pias;
	}
}